﻿using System;
using System.Drawing;
using System.IO;
using Aspose.Cells;

namespace Sys.Excel.Aspose
{
    public sealed class Aspose_Cells_ExcelExporter : ExcelExporterBase<Workbook, Worksheet, Style>
    {
        #region [ private ]

        private StyleFlag m_flag = new StyleFlag() { All = true };

        #endregion

        #region [ ExcelExporterBase<Workbook, Worksheet> ]

        protected override Workbook CreateWorkBook(bool useOldVersion)
        {
            var workbook = new Workbook(useOldVersion ? FileFormatType.Excel97To2003 : FileFormatType.Xlsx);
            workbook.Worksheets.Clear();
            return workbook;
        }

        protected override Worksheet CreateWorkSheet(Workbook workbook, string name, Settings settings)
        {
            Worksheet sheet = workbook.Worksheets.Add(name);
            sheet.Cells.StandardHeight = 20;
            return sheet;
        }

        protected override Style CreateCellStyle(Workbook workbook, Style style, CellStyle cellStyle)
        {
            style = style ?? workbook.CreateStyle();

            style.ForegroundColor = cellStyle.BgColor;

            TextAlignmentType h_align = TextAlignmentType.Center;
            Enum.TryParse<TextAlignmentType>(cellStyle.TextAlign.ToString(), out h_align);
            style.Pattern = BackgroundType.Solid;
            style.VerticalAlignment = TextAlignmentType.Center;
            style.HorizontalAlignment = h_align;

            style.Borders[BorderType.LeftBorder].Color =
                style.Borders[BorderType.TopBorder].Color =
                style.Borders[BorderType.RightBorder].Color =
                style.Borders[BorderType.BottomBorder].Color = Color.Black;

            style.Borders[BorderType.LeftBorder].LineStyle =
                style.Borders[BorderType.TopBorder].LineStyle =
                style.Borders[BorderType.RightBorder].LineStyle =
                style.Borders[BorderType.BottomBorder].LineStyle = CellBorderType.Thin;

            style.Font.IsBold = cellStyle.FontWeight == CellStyle.FontBoldWeight.Bold;
            style.Font.Color = cellStyle.FgColor;

            return style;
        }

        protected override Style GetCellStyle(
            Workbook workbook, Worksheet sheet, int row, int col)
        {
            return sheet.Cells[row, col].GetStyle();
        }

        protected override void SetCell(
            Workbook workbook, Worksheet sheet, int row,
            int col, Settings settings, ColNode node, object value, Style style,
            bool setValue = true, bool setStyle = true)
        {
            if (setValue || setStyle)
            {
                Cell cell = sheet.Cells[row, col];
                if (setValue) cell.PutValue(value == null ? null : value.ToString());
                if (setStyle) cell.SetStyle(style, this.m_flag);
            }
        }

        protected override void MergeCells(
            Workbook workbook, Worksheet sheet, int startRow,
            int endRow, int startCol, int endCol, Settings settings)
        {
            sheet.Cells.Merge(startRow, startCol, endRow - startRow + 1, endCol - startCol + 1);
        }

        protected override void FreezePane(
            Workbook workbook, Worksheet sheet, int rowSplit, int colSplit)
        {
            sheet.FreezePanes(rowSplit, colSplit, rowSplit + 1, colSplit + 1);
        }

        protected override void SetColumnsWidth(
            Workbook workbook, Worksheet sheet, Settings settings, uint[] widthArray, int startCol)
        {
            for (int i = 0; i < settings.LeafNodes.Count; i++)
            {
                sheet.Cells.Columns[startCol + i].Width = (int)widthArray[i];
            }
        }

        protected override void AutoFillColumns(
            Workbook workbook, Worksheet sheet, Settings settings, int startCol)
        {
            sheet.AutoFitColumns(new AutoFitterOptions() { AutoFitMergedCells = true });
        }

        protected override void Save(Workbook workbook, bool useOldVersion, Stream stream)
        {
            workbook.Save(stream,
                useOldVersion ? SaveFormat.Excel97To2003 : SaveFormat.Xlsx);
        }

        #endregion
    }
}